package monitor

import (
	"fmt"
	"github.com/prometheus/client_golang/api"
	"github.com/prometheus/client_golang/api/prometheus/v1"
	"time"
	"github.com/prometheus/common/model"
	"context"
	"strings"
	"strconv"
)

type Domain string

type ApiStatus struct {
	Url string					`json:"url"`
	ResponseCode string			`json:"responseCode"`
	ResponseTime string		`json:"responseTime"`
}


func (d Domain) Status() (currstatus []ApiStatus,err error) {
	cfg := api.Config{
		Address: prometheusServer,
	}
	proCli,err := api.NewClient(cfg)
	if err != nil {
		fmt.Println("connect to err is" , err.Error())
	}
	proApi := v1.NewAPI(proCli)
	ctx := context.Background()


	//q := fmt.Sprintf("irate(mysql_global_status_handlers_total{instance=~'%s.*',handler=~'commit|rollback|savepoint.*|prepare'}[5m])")
	q := "base_api_request_status"
	res,errr := proApi.Query(ctx,q,time.Time{})
	if errr != nil {
		fmt.Println("disk io error is",errr.Error())
	}
	//fmt.Println("disk io data is " , res)
	m,ok := res.(model.Vector)
	if ok {
		for _,a := range m {

			currstatus = append(currstatus,ApiStatus{
				Url: string(a.Metric["url"]),
				ResponseCode: string(a.Metric["code"]),
				//ny := fmt.Sprintf("%.2f",y),
				ResponseTime:  fmt.Sprintf("%.2f",float64(a.Value)),
			})

		}
	}


	return
}

type RestResponseDistribution struct {
	Url string 					`json:"url"`

	CodeSlice []string			`json:"codeslice"`
	Distribution []PieStruct 	`json:"distribution"`

	ResponseTrend IOSlice		`json:"responsetrend"`

}

type PieStruct struct {
	Name string				`json:"name"`
	Value int				`json:"value"`
}

func (r *RestResponseDistribution) CodeDistribution()  {
	fmt.Println("R is  " ,r)
	cfg := api.Config{
		Address: prometheusServer,
	}
	proCli,err := api.NewClient(cfg)
	if err != nil {
		fmt.Println("connect to err is" , err.Error())
	}
	proApi := v1.NewAPI(proCli)
	ctx := context.Background()

	q := fmt.Sprintf("base_api_request_status{url='%s'}[1h]",strings.TrimSpace(r.Url))
	fmt.Println(q)
	res,errr := proApi.Query(ctx,q,time.Time{})
	if errr != nil {
		fmt.Println("disk io error is",errr.Error())
	}
	//fmt.Println("disk io data is " , res)
	m,ok := res.(model.Matrix)
	fmt.Println(ok)
	if ok {
		for _,a := range m {
			fmt.Println(a.Metric["code"])
			fmt.Println(len(a.Values))
			r.CodeSlice = append(r.CodeSlice,string(a.Metric["code"]))
			r.Distribution = append(r.Distribution,PieStruct{
				Name: string(a.Metric["code"]),
				Value: len(a.Values),
			})
		}
	}

}


func (r *RestResponseDistribution) Trend()  {
	fmt.Println("R is  " ,r)
	cfg := api.Config{
		Address: prometheusServer,
	}
	proCli,err := api.NewClient(cfg)
	if err != nil {
		fmt.Println("connect to err is" , err.Error())
	}
	proApi := v1.NewAPI(proCli)
	ctx := context.Background()

	q := fmt.Sprintf("base_api_request_status{url='%s',code='200'}",strings.TrimSpace(r.Url))
	fmt.Println(q)

	t := v1.Range{
		End: time.Now(),
		Start: time.Now().Add(-time.Minute * 60),    //一小时内的
		Step: 300 * time.Second,
	}


	res,errr := proApi.QueryRange(ctx,q,t)
	if errr != nil {
		fmt.Println("disk io error is",errr.Error())
	}
	//fmt.Println("disk io data is " , res)
	m,ok := res.(model.Matrix)

	if ok && m.Len() > 0 {
		fmt.Println("m[0] is ",m[0].Metric)
		//fmt.Println("m[0] is ",m[0].Values)
		v := m[0].Values
		fmt.Println("len is",len(v))
		//fmt.Println(reflect.TypeOf(m[0].Values))
		for _,samplepair := range v {
			t := samplepair.Timestamp.Time().Format("15:04")
			y,_ := strconv.ParseFloat(samplepair.Value.String(),64)
			ny := fmt.Sprintf("%.2f",y)

			r.ResponseTrend.T = append(r.ResponseTrend.T,t)
			r.ResponseTrend.X1 = append(r.ResponseTrend.X1,ny)

		}
	}

}